home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i021: VN newsreader, 1/88 version, Part03/05
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Bob Mcqueer <amdahl!rtech!rtech!bobm@UUNET.UU.NET>
- Posting-number: Volume 13, Issue 21
- Archive-name: vn.jan.88/part03
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # envir_set.c
- # getch.c
- # hash.c
- # newdisp.c
- # printex.c
- # reg.c
- # sig_set.c
- # stat.c
- # storage.c
- # strings.c
- # strtok.c
- # svart.c
- # term_set.c
- # tmpnam.c
- # tty_set.c
- # userlist.c
- # vnglob.c
- # This archive created: Sat Jan 9 12:40:08 1988
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'envir_set.c'" '(2837 characters)'
- if test -f 'envir_set.c'
- then
- echo shar: will not over-write existing file "'envir_set.c'"
- else
- cat << \SHAR_EOF > 'envir_set.c'
- /*
- ** vn news reader.
- **
- ** envir_set.c - routine to obtain pertinent environment variable settings
- ** and set up file / directory names
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include <pwd.h>
- #include <sys/param.h>
- #include "tune.h"
- #include "config.h"
- #include "vn.h"
-
- extern char *Editor, *Ps1, *Printer;
- extern char *Orgdir, *Savedir, *Ccfile; /* path names */
- extern char Cxitop[], Cxitor[], Cxrtoi[], Cxptoi[];
- extern char *Home;
- extern int More;
-
- #ifdef SYSV
- extern char *getcwd();
- #define getwd(a) getcwd(a,sizeof(a))
- #define MAXPATHLEN 240
- #else
- extern char *getwd();
- #endif
-
- /*
- environment variable, original directory string setup.
- */
-
- envir_set ()
- {
- char dbuf [MAXPATHLEN], *ccname, *keyxln;
- char *vn_env(), *getcwd(), *str_store();
- struct passwd *ptr, *getpwuid();
-
- vns_envir();
- More = 0;
-
- Ps1 = vn_env("PS1",DEF_PS1);
- Editor = vn_env("EDITOR",DEF_ED);
- Printer = vn_env("PRINTER",DEF_PRINT);
- ccname = vn_env("CCFILE",DEF_CCFILE);
- keyxln = vn_env("VNKEY",DEF_KEYXLN);
- Savedir = vn_env("VNSAVE",NULL);
- More = (strcmp(vn_env("MORE",""), "-c") == 0 ? TRUE : FALSE);
-
- /*
- set original directory strings.
- */
-
- if ((ptr = getpwuid(getuid())) == NULL)
- printex("Cannot obtain /etc/passwd entry");
- Home = str_store(ptr->pw_dir);
- if ((Orgdir = getwd(dbuf)) == NULL)
- printex ("cannot stat pwd");
- Orgdir = str_store (Orgdir);
- if (Savedir == NULL)
- Savedir = Orgdir;
- if (*ccname != '/')
- {
- sprintf (dbuf, "%s/%s",Home,ccname);
- Ccfile = str_store (dbuf);
- }
- else
- Ccfile = str_store (ccname);
- sprintf (dbuf, "%s/%s%s",Home,".vn","XXXXXX");
-
- if (*keyxln != '/')
- {
- sprintf(dbuf, "%s/%s",Home,keyxln);
- set_kxln(dbuf);
- }
- else
- set_kxln(keyxln);
- }
-
- char *
- vn_env(var,def)
- char *var;
- char *def;
- {
- char pfx[RECLEN];
- char *res;
- char *getenv();
-
- if (var[0] != 'V' || var[1] != 'N')
- {
- sprintf(pfx,"VN%s",var);
- if ((res = getenv(pfx)) != NULL)
- return(res);
- }
-
- if ((res = getenv(var)) != NULL)
- return(res);
-
- return(def);
- }
-
- static
- set_kxln(fname)
- char *fname;
- {
- FILE *fp;
- int i;
- char bufr[80];
- char in,out,*ptr;
- char *index(), xln_str();
-
- for (i=0; i < 128; ++i)
- Cxitop[i] = Cxitor[i] = Cxptoi[i] = Cxrtoi[i] = i;
-
- if ((fp = fopen(fname,"r")) != NULL)
- {
- while(fgets(bufr,79,fp) != NULL)
- {
- if (strncmp(bufr+1,"==",2) == 0)
- ptr = bufr+2;
- else
- ptr = index(bufr+1,'=');
- if (ptr == NULL)
- continue;
- *ptr = '\0';
- ++ptr;
- in = xln_str(bufr+1);
- out = xln_str(ptr);
- switch(bufr[0])
- {
- case 'r':
- case 'R':
- Cxrtoi[out] = in;
- Cxitor[in] = out;
- break;
- case 'p':
- case 'P':
- Cxptoi[out] = in;
- Cxitop[in] = out;
- default:
- break;
- }
- }
- fclose(fp);
- }
- }
-
- static char
- xln_str(s)
- char *s;
- {
- if (*s < '0' || *s > '9')
- return(*s & 0x7f);
- return((char)(atoi(s) & 0x7f));
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'getch.c'" '(1924 characters)'
- if test -f 'getch.c'
- then
- echo shar: will not over-write existing file "'getch.c'"
- else
- cat << \SHAR_EOF > 'getch.c'
- /*
- ** vn news reader.
- **
- ** getch.c - character i/o routines
- **
- ** see copyright disclaimer / history in vn.c source file
- */
- #include <stdio.h>
- #include <setjmp.h>
- #include "config.h"
- #include "vn.h"
-
- extern char Cxitop[];
- extern char *Ku, *Kd, *Kr, *Kl;
-
- /*
- getkey obtains user keystroke with count from leading
- numerics, if any. Picks up arrow key sequences and maps
- them to other keys. Also translates character through
- Cxitop array since this routine is only used in session
- loop. Saves untranslating arrow keys.
- */
- getkey (c)
- char *c;
- {
- int i, j;
- static char ckseq[32];
-
- /* Check for leading count */
- for (i = 0; (*c = getchar() & 0x7f) >= '0' && *c <= '9'; i = i * 10 + *c - '0')
- ;
-
- /* @#$!!! flakey front ends that won't map newlines in raw mode */
- if (*c == '\012' || *c == '\015')
- *c = '\n';
-
- /* @#$!!! flakey terminals which send control sequences for cursors! */
- if( *c == '\033' )
- {
- /*
- ** Check if part of cursor key input sequence
- ** (pitch unknown escape sequences)
- */
- j = 0;
- ckseq[j] = *c; ckseq[j+1] = '\0';
- while(*c == Ku[j] || *c == Kd[j] || *c == Kl[j] || *c == Kr[j])
- {
- if( strcmp(ckseq, Ku) == 0 ) { *c = UP; break; }
- if( strcmp(ckseq, Kd) == 0 ) { *c = DOWN; break; }
- #ifdef PAGEARROW
- if( strcmp(ckseq, Kl) == 0 ) { *c = BACK; break; }
- if( strcmp(ckseq, Kr) == 0 ) { *c = FORWARD; break; }
- #else
- if( strcmp(ckseq, Kl) == 0 ) { *c = UP; break; }
- if( strcmp(ckseq, Kr) == 0 ) { *c = DOWN; break; }
- #endif
- *c = (getchar() & 0x7f);
- ckseq[++j] = *c; ckseq[j+1] = '\0';
- }
- }
- else
- *c = Cxitop[*c];
-
- if (i <= 0)
- i = 1;
- return (i);
- }
-
- /*
- get user key ignoring most controls. Used from reader and other
- non-screen interactions.
- */
- getnoctl ()
- {
- char c;
- while ((c = getchar() & 0x7f) < ' ' || c == '\177')
- {
- if (c == '\015' || c == '\012')
- c = '\n';
- if (c == '\n' || c == '\b' || c == '\t')
- return (c);
- }
- return ((int) c);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'hash.c'" '(1874 characters)'
- if test -f 'hash.c'
- then
- echo shar: will not over-write existing file "'hash.c'"
- else
- cat << \SHAR_EOF > 'hash.c'
- /*
- ** vn news reader.
- **
- ** hash.c - hash table routines
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include "config.h"
- #include "tune.h"
- #include "node.h"
-
- /*
- ** hash table manipulation routines:
- */
-
- extern int Ncount;
- extern NODE **Newsorder;
-
- static NODE *Tab [HASHSIZE]; /* hash Table */
-
- hashinit ()
- {
- int i;
- for (i=0; i < HASHSIZE; ++i)
- Tab[i] = NULL;
- Ncount = 0;
- }
-
- /*
- enter new node (name s, articles n, low l) in hash Table,
- initial flags = 0. Set order to -1.
- */
- NODE *hashenter(s,n,l)
- char *s;
- int n;
- int l;
- {
- char *str_store();
- NODE *ptr,*node_store();
- NODE *hashfind();
- int i;
-
- if ((ptr = hashfind(s)) != NULL)
- {
- fgprintf ("Warning: group %s encountered twice",s);
- return (ptr);
- }
-
- i=hash(s);
- ptr = node_store();
- ptr->next = Tab[i];
- Tab[i] = ptr;
- if (l > n)
- l = n;
- ++Ncount;
- ptr->lownum = l;
- ptr->state = 0;
- ptr->data = NULL;
- ptr->flags = 0;
- ptr->highnum = n;
- ptr->nd_name = str_store(s);
- ptr->pgshwn = 0;
- ptr->order = -1;
- return (ptr);
- }
-
- NODE *hashfind(s)
- char *s;
- {
- NODE *ptr;
-
- for (ptr = Tab[hash(s)]; ptr != NULL && strcmp(ptr->nd_name,s) != 0;
- ptr = ptr->next)
- ;
- return (ptr);
- }
-
- make_newsorder()
- {
- char *malloc();
- int i;
- NODE *ptr;
-
- if ((Newsorder = (NODE **) malloc(Ncount * sizeof(NODE *))) == NULL)
- printex("Memory allocation failure - newsorder array");
- for (i=0; i < Ncount; ++i)
- Newsorder[i] = NULL;
- for (i=0; i < HASHSIZE; ++i)
- {
- for (ptr = Tab[i]; ptr != NULL; ptr = ptr->next)
- {
- if (ptr->order < 0 || ptr->order >= Ncount)
- printex("News order range error");
- Newsorder[ptr->order] = ptr;
- }
- }
- for (i=0; i < Ncount; ++i)
- if (Newsorder[i] == NULL)
- printex("News order duplication error");
- }
-
- static hash (s)
- char *s;
- {
- unsigned rem;
- for (rem=0; *s != '\0'; ++s)
- rem = (rem*128 + (*s&0x7f)) % HASHSIZE;
- return (rem);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'newdisp.c'" '(920 characters)'
- if test -f 'newdisp.c'
- then
- echo shar: will not over-write existing file "'newdisp.c'"
- else
- cat << \SHAR_EOF > 'newdisp.c'
- /*
- ** vn news reader.
- **
- ** newgroups.c - display list of new groups since user's last ession.
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include "config.h"
- #include "tty.h"
- #include "node.h"
-
- extern NODE **Newsorder;
- extern int Ncount, Lrec, C_allow;
-
- new_groups ()
- {
- int i,wrem,w;
- int max;
- char fs[24],c_end;
-
- max = 0;
- for (i=0; i < Ncount; ++i)
- if (((Newsorder[i])->flags & FLG_NEW) != 0 &&
- (w = strlen((Newsorder[i])->nd_name)) > max)
- max = w;
- sprintf (fs,"%%-%ds%%c",max);
-
- if (max <= 0)
- return (0);
-
- term_set (ERASE);
- printf ("New newsgroups:\n");
-
- wrem = C_allow;
- for (i=0; i < Ncount; ++i)
- {
- if (((Newsorder[i])->flags & FLG_NEW) == 0)
- continue;
- if ((wrem -= max) < max)
- {
- wrem = C_allow;
- c_end = '\n';
- }
- else
- c_end = ' ';
- printf (fs,(Newsorder[i])->nd_name,c_end);
- }
- if (c_end != '\n')
- putchar ('\n');
-
- return (1);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'printex.c'" '(678 characters)'
- if test -f 'printex.c'
- then
- echo shar: will not over-write existing file "'printex.c'"
- else
- cat << \SHAR_EOF > 'printex.c'
- /*
- ** vn news reader.
- **
- ** printex.c - print fatal error message and exit.
- **
- ** see copyright disclaimer / history in vn.c source file
- */
- #include <stdio.h>
- #include <setjmp.h>
- #include "config.h"
- #include "tty.h"
-
- extern int errno; /* unix error number */
-
- /*
- error/abnormal condition cleanup and abort routine
- pass stack to printf
- */
- printex (s,a,b,c,d,e,f)
- char *s;
- long a,b,c,d,e,f;
- {
- static int topflag=0;
- if (topflag == 0)
- {
- ++topflag;
- term_set (STOP);
- tty_set (COOKED);
- fflush (stdout);
- fprintf (stderr,s,a,b,c,d,e,f);
- fprintf (stderr," (error code %d)\n",errno);
- vns_exit(1);
- stat_end(-1);
- exit (1);
- }
- else
- fprintf (stderr,s,a,b,c,d,e,f);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'reg.c'" '(1656 characters)'
- if test -f 'reg.c'
- then
- echo shar: will not over-write existing file "'reg.c'"
- else
- cat << \SHAR_EOF > 'reg.c'
- /*
- ** vn news reader.
- **
- ** reg.c - implementation of regex / regcmp on top of UCB library
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
-
- #define RGBLKSIZE 20
-
- struct _regtab
- {
- struct _regtab *link;
- char *regstr;
- };
-
- typedef struct _regtab REGTAB;
-
- static REGTAB *Chain = NULL;
- static REGTAB *Free = NULL;
- static REGTAB *Compiled = NULL;
-
- regfree(s)
- char *s;
- {
- REGTAB *ptr,*cmp,*old;
-
- cmp = (REGTAB *) s;
- old = NULL;
-
- for (ptr = Chain; ptr != NULL; ptr = (old = ptr)->link)
- {
- if (ptr == cmp)
- {
- if (old == NULL)
- Chain = Chain->link;
- else
- old->link = ptr->link;
- ptr->link = Free;
- Free = ptr;
- break;
- }
- }
- }
-
- char *regcmp(str)
- char *str;
- {
- int i;
- char *str_store();
- char *re_comp();
-
- if (re_comp(str) != NULL)
- {
- Compiled = NULL; /* make sure we're OK */
- return(NULL);
- }
-
- if (Free == NULL)
- {
- Free = (REGTAB *) malloc(RGBLKSIZE * sizeof(REGTAB));
- if (Free == NULL)
- printex ("regcmp: memory allocation failure");
- for (i = 0; i < RGBLKSIZE - 1; ++i)
- Free[i].link = Free + i + 1;
- Free[i].link = NULL;
- }
-
- Compiled = Free;
- Free = Free->link;
-
- Compiled->link = Chain;
- Chain = Compiled;
- Compiled->regstr = str_store(str);
-
- return ((char *) Compiled);
- }
-
- char *regex(reg,str)
- char *reg,*str;
- {
- REGTAB *cmp;
-
- cmp = (REGTAB *) reg;
-
- if (cmp == Compiled)
- {
- if (re_exec(str))
- return(str);
- return (NULL);
- }
-
- for (Compiled = Chain; Compiled != NULL; Compiled = Compiled->link)
- {
- if (Compiled == cmp)
- break;
- }
-
- if (Compiled == NULL)
- printex ("regex: bad pointer");
-
- re_comp(Compiled->regstr);
-
- if (re_exec(str))
- return(str);
-
- return(NULL);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'sig_set.c'" '(4477 characters)'
- if test -f 'sig_set.c'
- then
- echo shar: will not over-write existing file "'sig_set.c'"
- else
- cat << \SHAR_EOF > 'sig_set.c'
- /*
- ** vn news reader.
- **
- ** sig_set.c - signal handler
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include <sys/signal.h>
- #include <sgtty.h>
- #include <setjmp.h>
- #include "tty.h"
- #include "config.h"
- #include "brk.h"
- #include "tune.h"
- #include "node.h"
- #include "page.h"
-
- extern int L_allow;
- extern char *Version;
- extern char *Brk_fmt;
- extern char *Vns_version;
-
- static int Sigflag=BRK_INIT; /* phase of interaction */
- static FILE **Fpseek; /* article reading file pointer pointer */
- static int Foreground;
- static jmp_buf Jumploc; /* for BRK_SESS phase */
- static int Need_restart = 0;
-
- /*
- interrupt handler - unusual termination (longjmp and printex aborts)
- if not abort, remember to reset signal trap
- CAUTION - the passing of a jump buffer is a little dicey - assumes
- type jump_buf is an array.
-
- sigcatch and sig_set control a lot of i/o on stderr also, since
- it is so intimately related to signal interaction. Note that the
- SIGTSTP action causes a "stopped on tty output" if raw terminal
- mode is restored by tty_set(RESTORE). We don't get it if we were
- already cooked since tty_set avoids calling ioctl if it doesn't
- have to.
- */
- static sigcatch (sig)
- int sig;
- {
- char buf [MAX_C+1];
- int pgrp;
-
- /* disable signal while processing it */
- signal (sig,SIG_IGN);
-
- switch (sig)
- {
- case SIGINT:
- case SIGQUIT:
- break;
-
- #ifdef JOBCONTROL
- case SIGTSTP:
- /* ignore SIGTTOU so we don't get stopped if [kc]sh grabs the tty */
- signal(SIGTTOU, SIG_IGN);
- tty_set (SAVEMODE);
- term_set (MOVE,0,L_allow+RECBIAS-1);
- printf ("\n");
- Foreground = 0;
- fflush (stdout);
- fflush (stderr);
- signal(SIGTTOU, SIG_DFL);
-
- /* Send the TSTP signal to suspend our process group */
- signal(SIGTSTP, SIG_DFL);
- sigsetmask(0);
- kill (0, SIGTSTP);
-
- /* WE ARE NOW STOPPED */
-
- /*
- WELCOME BACK!
- if terminals process group is ours, we are foregrounded again
- and can turn newsgroup name printing back on
- */
- tty_set (RESTORE);
-
- /*
- ** Note concerning RESTART. If in state BRK_IN, we simply
- ** set a flag to do it upon switch to state BRK_SESS - we
- ** don't want to send i/o to the terminal when we
- ** background during BRK_IN phase ("stopped on tty output")
- */
- switch (Sigflag)
- {
- case BRK_SESS:
- signal (SIGTSTP,sigcatch);
- term_set (RESTART);
- longjmp (Jumploc,1);
- case BRK_IN:
- Need_restart = 1;
- ioctl (1,TIOCGPGRP,&pgrp);
- if (pgrp == getpgrp(0))
- Foreground = 1;
- break;
- default:
- term_set (RESTART);
- break;
- }
- signal (SIGTSTP,sigcatch);
- return;
- #endif
- default:
- printex (Brk_fmt,sig);
- }
-
- /* QUIT and INTERRUPT signals */
- switch (Sigflag)
- {
- case BRK_SESS:
- /* if in session, ask if really a quit, do longjump if not */
- term_set (ERASE);
- tty_set (RAWMODE);
- user_str (buf, BRK_PR, 1, "");
- if (buf[0] == 'y')
- printex (Brk_fmt,sig);
- signal (sig,sigcatch);
- longjmp (Jumploc,1);
- case BRK_READ:
- /* if reading seek file to end to abort page printing */
- printf ("\n");
- if (*Fpseek == NULL || fseek(*Fpseek,0L,2) < 0)
- putchar ('\07');
- break;
- default:
- printex (Brk_fmt,sig);
- }
- signal (sig,sigcatch);
- }
-
- /*
- sig_set controls what will be done with a signal when picked up by
- sigcatch. fgprintf is included here to keep knowledge
- of TSTP state localized.
- */
- /* VARARGS */
- sig_set (flag,dat)
- int flag, *dat;
- {
- int i, *xfer, pgrp;
- if (Sigflag == BRK_INIT)
- {
- signal (SIGINT,sigcatch);
- signal (SIGQUIT,sigcatch);
- signal (SIGTERM,sigcatch);
- #ifdef JOBCONTROL
- signal (SIGTSTP,sigcatch);
- ioctl (1,TIOCGPGRP,&pgrp);
- if (pgrp == getpgrp(0))
- {
- Foreground = 1;
- fgprintf ("Visual News, %s(%s), reading:\n",
- Version, Vns_version);
- }
- else
- Foreground = 0;
- #else
- Foreground = NOJOB_FG;
- #endif
- }
- switch (flag)
- {
- case BRK_IN:
- case BRK_OUT:
- Sigflag = flag;
- break;
- case BRK_READ:
- if (Sigflag != BRK_SESS)
- printex ("unexpected read state, sig_set\n");
- Fpseek = (FILE **) dat;
- Sigflag = BRK_READ;
- break;
- case BRK_SESS:
- if (Need_restart)
- term_set(RESTART);
- xfer = (int *) Jumploc;
- for (i=0; i < sizeof(Jumploc) / sizeof(int); ++i)
- xfer[i] = dat[i];
- Sigflag = BRK_SESS;
- break;
- case BRK_RFIN:
- if (Sigflag != BRK_READ)
- printex ("unexpected finish state, sig_set\n");
- Sigflag = BRK_SESS;
- break;
- default:
- printex ("bad state %d, sig_set\n",flag);
- }
- }
-
- fgprintf (fs,a,b,c,d,e)
- char *fs;
- int a,b,c,d,e;
- {
- if (Foreground)
- fprintf (stderr,fs,a,b,c,d,e);
- fflush (stderr);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'stat.c'" '(4226 characters)'
- if test -f 'stat.c'
- then
- echo shar: will not over-write existing file "'stat.c'"
- else
- cat << \SHAR_EOF > 'stat.c'
- /*
- ** vn news reader.
- **
- ** stat.c - stat and log file collection
- **
- ** see copyright disclaimer / history in vn.c source file
- */
- #include <stdio.h>
- #include <sys/types.h>
- #ifdef SYSV
- #include <fcntl.h>
- #endif
- #include <sys/file.h>
- #include <sys/stat.h>
- #include <pwd.h>
- #include "config.h"
- #include "node.h"
-
- extern NODE *hashfind();
- extern char *strtok();
- extern int Ncount;
- extern NODE **Newsorder;
-
- #ifdef VNLOGFILE
- static char Start[80];
- #endif
-
- stat_start()
- {
- #ifdef VNLOGFILE
- char *ctime();
- long now;
-
- time(&now);
- strcpy(Start,ctime(&now));
- #endif
- }
-
- /*
- ** flag = 0, "NO NEWS" type session.
- ** = 1, regular session.
- ** = -1, aborted session
- **
- ** CAUTION: routine CALLED from within printex() - do NOT
- ** call printex(). Simply do message to stderr on fail.
- */
- stat_end(flag)
- int flag;
- {
- NODE *nd;
- char *nl,*index();
- char *how;
- struct passwd *ptr, *getpwuid();
- struct stat buf;
- long now;
- char bufr[80];
- char name[60];
- FILE *fp;
- int fd;
- long chk, rd, pg;
- int i;
-
- #ifdef VNLOGFILE
- if (stat(VNLOGFILE,&buf) == 0 && (fp = fopen(VNLOGFILE,"a")) != NULL)
- {
- time(&now);
- strcpy(bufr,ctime(&now));
- if ((nl = index(bufr,'\n')) != NULL)
- *nl = '\0';
- if ((nl = index(Start,'\n')) != NULL)
- *nl = '\0';
- if (flag == 0)
- how = "NO NEWS";
- else
- {
- if (flag > 0)
- how = "OK";
- else
- how = "ABORTED";
- }
- ptr = getpwuid (getuid());
- fprintf(fp, "%s\t%s - %s %s\n", ptr->pw_name, Start, bufr, how);
- fclose (fp);
- }
- #endif
-
- #ifdef VNSTATFILE
- /*
- ** Stat file is done with a fixed record size, and maintaining the
- ** existing record order exactly so that concurrent users will do
- ** the least damage. If two users actually read & update a single
- ** record simultaneously, we should just lose one user's counts.
- ** Short of implementing a locking scheme, we probably won't do
- ** much better. Disadvantages are that deleted newsgroups never
- ** get cleaned out, order is set by the first user whose
- ** statistics are collected, it will break if anyone modifies it,
- ** and the file is a bit larger than it needs to be.
- **
- ** record format:
- **
- ** CCCCCC PPPPPP RRRRRR newsgroup name .... \n
- ** ^ ^ ^ ^ ^
- ** 0 7 14 21 char 79
- **
- ** CCCCCC - count of sessions searching group
- ** PPPPPP - count of sessions actually finding pages for group
- ** RRRRRR - count of sessions actually accessing articles in group
- */
- if ((fd = open(VNSTATFILE,O_RDWR)) > 0)
- {
- bufr[80] = '\0';
-
- /*
- ** read a record, find the newsgroup, update counts.
- ** If changed, seek back & overwrite. By using fixed
- ** length records, we should only lose something on
- ** concurrent writes of the same record, and by writing
- ** the ENTIRE record, we keep it consistent
- */
- while ((i = read(fd,bufr,80)) == 80 && bufr[79] == '\n')
- {
- chk = atoi(bufr);
- pg = atoi(bufr+7);
- rd = atoi(bufr+14);
- strcpy(name,bufr+21);
- nl = strtok(name," \n");
- if (nl == NULL || (nd = hashfind(nl)) == NULL)
- continue;
- nd->flags |= FLG_STAT;
- if ((nd->flags & (FLG_SEARCH|FLG_ACC|FLG_PAGE)) == 0)
- continue;
- if ((nd->flags & FLG_SEARCH) != 0)
- ++chk;
- if ((nd->flags & FLG_PAGE) != 0)
- ++pg;
- if ((nd->flags & FLG_ACC) != 0)
- ++rd;
- if (chk > 999999L)
- chk = 999999L;
- if (pg > 999999L)
- pg = 999999L;
- if (rd > 999999L)
- rd = 999999L;
- sprintf(bufr,"%6ld",chk);
- bufr[6] = ' ';
- sprintf(bufr+7,"%6ld",pg);
- bufr[13] = ' ';
- sprintf(bufr+14,"%6ld",rd);
- bufr[20] = ' ';
- lseek(fd,-80L,1);
- write(fd,bufr,80);
- }
-
- /* format screwed up ? */
- if (i != 0)
- {
- lseek(fd,(long) -i,1);
- fprintf(stderr,"bad data in %s\n",VNSTATFILE);
- }
-
- /* may have aborted during vns_news() */
- if (Newsorder == NULL)
- Ncount = 0;
-
- /* now append any groups not in file yet */
- for (i = 0; i < Ncount; ++i)
- {
- nd = Newsorder[i];
- if ((nd->flags & FLG_STAT) != 0)
- continue;
- chk = rd = pg = 0;
- if ((nd->flags & FLG_SEARCH) != 0)
- chk = 1;
- if ((nd->flags & FLG_PAGE) != 0)
- pg = 1;
- if ((nd->flags & FLG_ACC) != 0)
- rd = 1;
- sprintf(bufr,"%6ld %6ld %6ld %-58s\n",
- chk, pg, rd, nd->nd_name);
- write(fd,bufr,80);
- }
- close(fd);
- }
- #endif
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'storage.c'" '(2261 characters)'
- if test -f 'storage.c'
- then
- echo shar: will not over-write existing file "'storage.c'"
- else
- cat << \SHAR_EOF > 'storage.c'
- /*
- ** vn news reader.
- **
- ** storage.c - storage allocation routines
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include "tune.h"
- #include "node.h"
- #include "page.h"
-
- extern char *malloc();
-
- extern int L_allow;
-
- extern PAGE Page;
- /*
- Storage allocaters.
- */
-
- char *str_store (s)
- char *s;
- {
- static unsigned av_len = 0; /* current storage available */
- static char *avail;
- int len;
-
- if (s == NULL)
- s = "";
-
- if ((len = strlen(s)+1) > av_len)
- {
- if (len > STRBLKSIZE)
- av_len = len;
- else
- av_len = STRBLKSIZE;
- if ((avail = malloc(av_len)) == NULL)
- printex ("can't allocate memory for string storage");
- }
- strcpy (avail,s);
- s = avail;
- avail += len;
- av_len -= len;
- return (s);
- }
-
- /*
- ** called after number of terminal lines (L_allow) is known, to set
- ** up storage for Page.
- */
- page_alloc ()
- {
- char *body;
-
- if ((body = malloc(L_allow*sizeof(BODY))) == NULL)
- printex ("can't allocate memory for display storage");
-
- Page.b = (BODY *) body;
- }
-
- NODE
- *node_store()
- {
- static int nd_avail = 0;
- static NODE *nd;
- NODE *ret;
-
- if (nd_avail <= 0)
- {
- if ((nd = (NODE *) malloc(sizeof(NODE)*NDBLKSIZE)) == NULL)
- printex ("can't allocate memory for newsgroup table");
- nd_avail = NDBLKSIZE;
- }
- --nd_avail;
- ret = nd;
- ++nd;
- return(ret);
- }
-
- /*
- ** temp string storage
- */
-
- typedef struct
- {
- int len;
- int idx;
- char **ptr;
- } STRINGPOOL;
-
- char *
- str_tpool(n)
- int n;
- {
- int size;
- STRINGPOOL *p;
-
- size = sizeof(STRINGPOOL) + n * sizeof(char **);
-
- if ((p = (STRINGPOOL *) malloc(size)) == NULL)
- printex("Cannot allocate temporary string storage");
-
- p->ptr = (char **)(p+1);
- p->len = n;
- p->idx = 0;
-
- return((char *) p);
- }
-
- char *
- str_tstore(cp,s)
- char *cp;
- char *s;
- {
- STRINGPOOL *p;
- int len;
-
- p = (STRINGPOOL *) cp;
- if (p->idx >= p->len)
- printex("Temporary string storage overflow");
- len = strlen(s)+1;
- if ((cp = malloc(len)) == NULL)
- printex("Cannot allocate copy of string");
- strcpy(cp,s);
- (p->ptr)[p->idx] = cp;
- ++(p->idx);
-
- return(cp);
- }
-
- char **
- str_taptr(cp)
- char *cp;
- {
- STRINGPOOL *p;
-
- p = (STRINGPOOL *) cp;
-
- return (p->ptr + p->idx);
- }
-
- str_tfree(cp)
- char *cp;
- {
- STRINGPOOL *p;
- int i;
-
- p = (STRINGPOOL *) cp;
- for (i=0; i < p->idx; ++i)
- free((p->ptr)[i]);
- free (cp);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'strings.c'" '(537 characters)'
- if test -f 'strings.c'
- then
- echo shar: will not over-write existing file "'strings.c'"
- else
- cat << \SHAR_EOF > 'strings.c'
- /*
- ** vn news reader.
- **
- ** strings.c - read only character strings
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include "tune.h"
- #include "node.h"
- #include "page.h"
-
- char *Version = "1/88";
-
- char *No_msg = "No articles";
- char *Hdon_msg = "Headers being printed";
- char *Hdoff_msg = "Headers being suppressed";
- char *Roton_msg = "ROT 13";
- char *Rotoff_msg = "NO ROT";
-
- char *Aformat = AFORMAT;
-
- char *Contstr = " ******** any key to continue ********";
-
- char *Brk_fmt = "QUIT (signal %d)";
-
- char *List_sep = " \t,";
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'strtok.c'" '(1082 characters)'
- if test -f 'strtok.c'
- then
- echo shar: will not over-write existing file "'strtok.c'"
- else
- cat << \SHAR_EOF > 'strtok.c'
- /*
- ** vn news reader.
- **
- ** strtok.c - strtok() and strpbrk() string routines using UCB index().
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
-
- char *strpbrk (s,del)
- char *s, *del;
- {
- char *ptr,*index();
- if (s == NULL)
- return (NULL);
- for (; *del != '\0'; ++del)
- if ((ptr = index(s,*del)) != NULL)
- return (ptr);
- return (NULL);
- }
-
- char *strtok(str,delim)
- char *str, *delim;
- {
- char *tokstart, *tokend, *first_ch (), *last_ch();
- static char *save=NULL;
-
- if (str != NULL)
- save = str;
-
- if (save == NULL)
- return (NULL);
-
- tokstart = first_ch (save, delim);
- tokend = last_ch (tokstart, delim);
- save = first_ch (tokend, delim);
- *tokend = '\0';
-
- if (*tokstart == '\0')
- return (NULL);
-
- return (tokstart);
- }
-
- static char *first_ch (str,delim)
- char *str,*delim;
- {
- char *index ();
- char *f;
-
- for (f = str; *f != '\0' && index(delim,*f) != NULL; ++f)
- ;
-
- return (f);
- }
-
- static char *last_ch (str,delim)
- char *str,*delim;
- {
- char *index ();
- char *f;
-
- for (f = str; *f != '\0' && index(delim,*f) == NULL; ++f)
- ;
-
- return (f);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'svart.c'" '(4156 characters)'
- if test -f 'svart.c'
- then
- echo shar: will not over-write existing file "'svart.c'"
- else
- cat << \SHAR_EOF > 'svart.c'
- /*
- ** vn news reader.
- **
- ** svart.c - article save routine
- **
- ** see copyright disclaimer / history in vn.c source file
- */
- #include <stdio.h>
- #include <pwd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "config.h"
- #include "tty.h"
- #include "tune.h"
- #include "node.h"
- #include "page.h"
-
- extern PAGE Page;
- extern int Digest;
- extern char *List_sep;
- extern char *Home;
- extern char *Savedir;
-
- /*
- ** save article in file. Called from reader and session both.
- ** handles "|" pipe convention. Caller passes in return message buffer.
- */
- save_art(art,idest,msg)
- char *art;
- char *idest;
- char *msg;
- {
- char fn[L_tmpnam+1];
- char cmd[RECLEN];
- char *mode;
- char *dest, dstore[RECLEN];
- struct stat sbuf;
- int rstat;
- char *colon;
- char *pcnt;
- char *index();
-
- /* temporary copy so we don't overwrite saved string */
- strcpy((dest = dstore),idest);
-
- if (*dest == '|')
- {
- tmpnam(fn);
- if (art_xfer(fn,art,"w") != 0)
- {
- strcpy(msg,"Can't open temporary file");
- return (-1);
- }
- sprintf(cmd,"cat %s %s",fn,dest);
- tty_set (SAVEMODE);
- rstat = system (cmd);
- tty_set (RESTORE);
- sprintf(msg,"Command returns %d",rstat);
- return (rstat);
- }
-
- if ((colon = index(dest,':')) != NULL)
- {
- mode = dest;
- *colon = '\0';
- dest = colon+1;
- }
- else
- mode = "a";
-
- if (*dest == '~')
- {
- if (twiddle(dest,msg) < 0)
- return (-1);
- }
-
- if (*dest == '\0')
- strcpy(dest,"%d");
-
- if (*dest != '/')
- {
- if (noslash(dest,msg) < 0)
- return (-1);
- }
-
- if ((pcnt = index(dest,'%')) != NULL && pcnt[1] == 'd')
- {
- if (Digest)
- sprintf(cmd,dest,Digest);
- else
- sprintf(cmd,dest,atoi(art));
- dest = cmd;
- }
-
- rstat = stat(dest,&sbuf);
-
- if (art_xfer(dest,art,mode) != 0)
- {
- sprintf(msg,"Can't open %s with mode %s",dest,mode);
- return(-1);
- }
-
- if (rstat != 0)
- {
- sprintf(msg,"Created %s",dest);
- return(0);
- }
-
- if (strcmp(mode,"a") == 0)
- {
- sprintf(msg,"Appended %s",dest);
- return(0);
- }
-
- sprintf(msg,"Wrote (mode %s) %s",mode,dest);
- return(0);
- }
-
- static
- noslash(dest,msg)
- char *dest;
- char *msg;
- {
- char *pcnt;
- char buf[RECLEN];
- char dir[RECLEN];
- struct stat sbuf;
-
- strcpy(buf,Page.h.name);
- #ifdef SYSV
- buf[14] = '\0';
- #endif
- if ((pcnt = index(Savedir,'%')) != NULL && pcnt[1] == 's')
- sprintf(dir,Savedir,buf);
- else
- strcpy(dir,Savedir);
- if (dir[0] == '~')
- {
- if (twiddle(dir,msg) < 0)
- return (-1);
- }
- if (stat(dir,&sbuf) != 0)
- {
- #ifdef SYSV
- /*
- ** late enough releases of SYSV may have a mkdir() call, but
- ** this is an obscure feature anyway. We'll accept the fork.
- */
- sprintf(buf,"mkdir %s",dir);
- if (system(buf) != 0)
- #else
- if (mkdir(dir,0755) != 0)
- #endif
- {
- sprintf(msg,"Cannot make directory %s",dir);
- return (-1);
- }
- }
- sprintf(buf,"%s/%s",dir,dest);
- strcpy(dest,buf);
- return (0);
- }
-
- static
- twiddle(dest,msg)
- char *dest, *msg;
- {
- char *tail;
- char *name;
- char tmp;
- char buf[RECLEN];
- struct passwd *ptr, *getpwnam();
-
- for (tail=name=dest+1; *tail != '/' && *tail != '\0'; ++tail)
- ;
-
- if (*name == '\0' || *name == '/')
- sprintf(buf,"%s%s",Home,tail);
- else
- {
- tmp = *tail;
- *tail = '\0';
- ptr = getpwnam(name);
- *tail = tmp;
- if (ptr == NULL)
- {
- sprintf(msg,"Can't interpret ~%s",name);
- return(-1);
- }
- sprintf(buf,"%s%s",ptr->pw_dir,tail);
- }
-
- strcpy(dest,buf);
- return (0);
- }
-
- /*
- ** transfer contents of a list of articles to a file. If Digest, this
- ** is simply a list of files. If not, it is a list of articles to be
- ** saved with vns_asave. Parses list destructively with
- ** strtok(). Return 0 for success, -1 for failure to open file.
- **
- ** Called directly to copy a list of articles to a temp. file to
- ** direct to printer.
- */
- art_xfer(fn,list,mode)
- char *fn, *list, *mode;
- {
- char *p;
- FILE *fout, *fin;
- int count;
- char buf[RECLEN];
- char *strtok();
-
- if ((fout = fopen(fn,mode)) == NULL)
- return (-1);
-
- count = 0;
- for (p = strtok(list,List_sep); p != NULL; p = strtok(NULL,List_sep))
- {
- if (Digest)
- {
- fin = fopen(p,"r");
- if (fin == NULL)
- continue;
- while (fgets(buf,RECLEN-1,fin) != NULL)
- fputs(buf,fout);
- fclose(fin);
- continue;
- }
- vns_asave(atoi(p),fout,count,fn,mode);
- ++count;
- }
- fclose(fout);
- return(0);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'term_set.c'" '(4953 characters)'
- if test -f 'term_set.c'
- then
- echo shar: will not over-write existing file "'term_set.c'"
- else
- cat << \SHAR_EOF > 'term_set.c'
- /*
- ** vn news reader.
- **
- ** term_set.c - terminal control, hides termcap interface
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include "tty.h"
- #include "config.h"
- #include "tune.h"
- #include "node.h"
- #include "page.h"
-
- extern int L_allow, C_allow;
- extern char *Ku, *Kd, *Kl, *Kr;
-
- static outc (c)
- char c;
- {
- putchar (c);
- }
-
- /*
- term_set controls terminal through termcap
- START sets global parameters related to terminal also,
- as well as allocating display buffer which depends on
- terminal lines, and allocating escape strings. RESTART
- simply re-issues the initialization - used following system
- calls that could have goofed up the terminal state.
- */
-
- /*
- ** Escape strings.
- */
-
- static char *Cm,*Cl,*So,*Se,*Te,*Bc,*Ce,*Ti,*Ks,*Ke;
- #ifdef USEVS
- static char *Vs,*Ve;
- #endif
-
- static int Backspace; /* backspace works */
- static int Overstrike; /* terminal overstrikes */
-
- static t_setup()
- {
- char *tgetstr(), *vn_env(), *str_store();
- char *c, tc_buf[2048],optstr[2048];
- char *tvar;
-
- tvar = vn_env("TERM",DEF_TERM);
-
- c = optstr;
- if (tgetent(tc_buf,tvar) != 1)
- printex ("%s - unknown terminal",tvar);
-
- /* get needed capabilities */
- Cm = str_store(tgetstr("cm",&c));
- Cl = str_store(tgetstr("cl",&c));
- So = str_store(tgetstr("so",&c));
- Se = str_store(tgetstr("se",&c));
- Te = str_store(tgetstr("te",&c));
- Ti = str_store(tgetstr("ti",&c));
- Bc = str_store(tgetstr("bc",&c));
- Ce = str_store(tgetstr("ce",&c));
- Kd = str_store(tgetstr("kd",&c));
- Ke = str_store(tgetstr("ke",&c));
- Kl = str_store(tgetstr("kl",&c));
- Kr = str_store(tgetstr("kr",&c));
- Ks = str_store(tgetstr("ks",&c));
- Ku = str_store(tgetstr("ku",&c));
- #ifdef USEVS
- Vs = str_store(tgetstr("vs",&c));
- Ve = str_store(tgetstr("ve",&c));
- #endif
- Backspace = tgetflag("bs");
- Overstrike = tgetflag("os");
-
- if ( *Cm == '\0' || *Cl == '\0')
- {
- printex ("cursor control and erase capability needed");
- }
-
- /*
- ** Checks for arrow keys which don't issue something beginning
- ** with <ESC>. This is more paranoid than we need to be, strictly
- ** speaking - we could get away with any string which didn't
- ** conflict with controls used for commands. However, that would
- ** be a maintenance headache - we will simply reserve <ESC> as the
- ** only char not to be used for commands, and punt on terminals
- ** which don't send reasonable arrow keys. It would be confusing
- ** to have keys work partially, also. I know of no terminal with
- ** one arrow key beginning with an escape, and another beginning
- ** with something else, but let's be safe. This also insists on
- ** definitions for all 4 arrows, which seems reasonable.
- */
-
- if ((*Ku != '\0' && *Ku != '\033') || *Kl != *Ku || *Kr != *Ku || *Kd != *Ku)
- {
- fgprintf("WARNING: arrow keys will not work for this terminal");
- Ku = Kd = Kl = Kr = Kd = Ke = "";
- }
-
- if (Overstrike)
- fgprintf ("WARNING: terminal overstrikes - can't update display without erase\n");
-
- if ((L_allow = tgetnum("li")) < REQLINES)
- {
- if (L_allow < 0)
- printex ("can't determine number of lines on terminal");
- printex ("too few lines for display - %d needed", REQLINES);
- }
-
- /*
- ** C_allow set so as to not use extreme right column.
- ** Avoids "bad wraparound" problems - we're deciding it's best
- ** to ALWAYS assume no automargin, and take care of it ourselves
- */
- if((C_allow = tgetnum("co")) > MAX_C)
- C_allow = MAX_C;
- else
- --C_allow;
- if (C_allow < MIN_C)
- {
- if (C_allow < 0)
- printex("can't determine number of columns on terminal.");
- printex ("too few columns for display - %d needed",MIN_C);
- }
-
- L_allow -= RECBIAS;
- page_alloc();
- tputs(Ti,1,outc);
- tputs(Ks,1,outc);
- #ifdef USEVS
- tputs(Vs,1,outc);
- #endif
- }
-
- /* VARARGS */
- term_set(cmd,x,y)
- int cmd,x,y;
- {
- char *tgoto();
- int i;
- switch (cmd)
- {
- case MOVE:
- tputs (tgoto(Cm,x,y),1,outc);
- break;
- case ERASE:
- tputs(Cl,1,outc);
- break;
- case ONREVERSE:
- tputs(So,1,outc);
- break;
- case OFFREVERSE:
- tputs(Se,1,outc);
- break;
- case START:
- t_setup();
- break;
- case RESTART:
- tputs(Ti,1,outc);
- tputs(Ks,1,outc);
- #ifdef USEVS
- tputs(Vs,1,outc);
- #endif
- break;
- case STOP:
- term_set (MOVE,0,L_allow+RECBIAS-1);
- printf ("\n");
- tputs(Ke,1,outc);
- tputs(Te,1,outc);
- #ifdef USEVS
- tputs(Ve,1,outc);
- #endif
- break;
- case RUBSEQ:
- if (Overstrike)
- {
- /* space overprint is futile */
- if (Backspace)
- putchar('\010');
- else
- tputs(Bc,1,outc);
- break;
- }
- if (Backspace)
- printf("%c %c",'\010','\010');
- else
- {
- tputs(Bc,1,outc);
- putchar(' ');
- tputs(Bc,1,outc);
- }
- break;
- case ZAP:
- if (Ce != NULL && *Ce != '\0')
- tputs(Ce,1,outc);
- else
- {
- if (Overstrike)
- break; /* punt */
- for (i=x; i < y; ++i)
- putchar(' ');
- if (Backspace)
- {
- for (i=x; i < y; ++i)
- putchar('\010');
- }
- else
- {
- for (i=x; i < y; ++i)
- tputs(Bc,1,outc);
- }
- }
- break;
- default:
- printex ("term_set unknown code (%d)",cmd);
- break;
- }
- return (0);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'tmpnam.c'" '(420 characters)'
- if test -f 'tmpnam.c'
- then
- echo shar: will not over-write existing file "'tmpnam.c'"
- else
- cat << \SHAR_EOF > 'tmpnam.c'
- /*
- ** vn news reader.
- **
- ** tmpnam.c - tmpnam() replacement for UCB, also uses non-generic name.
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include "config.h"
-
- char *tmpnam (buf)
- char *buf;
- {
- static char *ptr = VNTEMPNAME;
-
- /* depends on string initialized above */
- sprintf (ptr+TMP_XOFFSET,"XXXXXX");
-
- mktemp (ptr);
-
- if (buf != NULL)
- strcpy (buf,ptr);
-
- return (ptr);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'tty_set.c'" '(2552 characters)'
- if test -f 'tty_set.c'
- then
- echo shar: will not over-write existing file "'tty_set.c'"
- else
- cat << \SHAR_EOF > 'tty_set.c'
- /*
- ** vn news reader.
- **
- ** tty_set.c - interface to ioctl (system tty interface)
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #ifdef SYSV
- #include <termio.h>
- #else
- #include <sgtty.h>
- #endif
-
- #include "tty.h"
-
- extern char Erasekey,Killkey;
-
- #ifdef SYSV
- static struct termio C_tp, O_tp;
- #else
- static struct sgttyb C_tp;
- static unsigned short O_lflag;
- #endif
-
- static unsigned S_flag=0;
- static int R_ignore=0; /* up/down counter of reset calls to ignore */
-
- #define IO_GOT 1 /* have polled for original terminal mode */
- #define IO_RAW 2 /* in RAW (CBREAK actually) mode */
-
- /*
- tty_set handles ioctl calls. SAVEMODE, RESTORE are used around
- system calls and interrupts to assure cooked mode, and restore
- raw if raw on SAVEMODE. The pair results in no calls to ioctl
- if we are cooked already when SAVEMODE is called, and may be nested,
- provided we desire no "restore" of cooked mode after restoring raw.
-
- When we get the original terminal mode, we also save erase and kill.
-
- sig_set makes an ioctl call to get process group leader. Otherwise
- ioctl calls should come through here.
- */
- tty_set(cmd)
- int cmd;
- {
- int rc;
- unsigned mask;
-
- switch (cmd)
- {
- case BACKSTOP:
- #ifdef JOBCONTROL
- if ((rc = ioctl(1,TIOCLGET,&mask)) != 0)
- break;
- mask |= LTOSTOP;
- rc = ioctl(1,TIOCLSET,&mask);
- #else
- rc = 0;
- #endif
- break;
- case RAWMODE:
- if ((S_flag & IO_RAW) != 0)
- {
- rc = 0;
- break;
- }
- if ((S_flag & IO_GOT) == 0)
- {
- /* Save original modes, get erase / kill */
- #ifdef SYSV
- rc = ioctl(0,TCGETA,&C_tp);
- O_tp = C_tp;
- Erasekey = C_tp.c_cc[VERASE];
- Killkey = C_tp.c_cc[VKILL];
- #else
- rc = ioctl(0,TIOCGETP,&C_tp);
- O_lflag = C_tp.sg_flags;
- Erasekey = C_tp.sg_erase;
- Killkey = C_tp.sg_kill;
- #endif
- }
- #ifdef SYSV
- C_tp.c_lflag &= ~(ECHO | ICANON);
- C_tp.c_cc[VMIN] = 1;
- rc = ioctl(0,TCSETAW,&C_tp);
- #else
- C_tp.sg_flags |= CBREAK;
- C_tp.sg_flags &= ~ECHO;
- rc = ioctl(0,TIOCSETP,&C_tp);
- #endif
- S_flag = IO_GOT|IO_RAW;
- break;
- case COOKED:
- if ((S_flag & IO_RAW) != 0)
- {
- #ifdef SYSV
- C_tp = O_tp;
- rc = ioctl(0,TCSETAW,&C_tp);
- #else
- C_tp.sg_flags = O_lflag;
- rc = ioctl(0,TIOCSETP,&C_tp);
- #endif
- S_flag &= ~IO_RAW;
- }
- else
- rc = 0;
- break;
- case SAVEMODE:
- if ((S_flag & IO_RAW) != 0)
- {
- tty_set(COOKED);
- R_ignore = 0;
- }
- else
- ++R_ignore;
- rc = 0;
- break;
- case RESTORE:
- if (R_ignore <= 0)
- {
- tty_set(RAWMODE);
- }
- else
- --R_ignore;
- rc = 0;
- break;
- default:
- rc = -1;
- }
- if (rc < 0)
- printex ("ioctl failure, tty_set: %d",cmd);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'userlist.c'" '(2130 characters)'
- if test -f 'userlist.c'
- then
- echo shar: will not over-write existing file "'userlist.c'"
- else
- cat << \SHAR_EOF > 'userlist.c'
- /*
- ** vn news reader.
- **
- ** userlist.c - generate user's list of articles
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include "tune.h"
- #include "node.h"
- #include "page.h"
- #include "vn.h"
-
- extern PAGE Page;
- extern char *List_sep;
-
- static char Pattern[MAX_C] = "";
-
- /*
- generate user list of articles - either article numbers
- are input directly (numeric list), or input is a search
- string - invoke regular expression library and examine titles
- search string "*" reserved for marked articles. Strings may
- be prefixed with '!' for negation.
- */
- userlist (list)
- char *list;
- {
- int i,j,anum[RECLEN/2],acount;
- char neg, *s, sbuf[MAX_C+1], *reg, *regex(), *regcmp(), *index(), *strtok();
-
- user_str (sbuf,"Articles or title search string : ",1,Pattern);
- if (sbuf[0] == '!')
- {
- neg = '!';
- s = sbuf+1;
- }
- else
- {
- neg = '\0';
- s = sbuf;
- }
- for (i=0; s[i] != '\0'; ++i)
- {
- if (index(List_sep,s[i]) == NULL)
- {
- if (s[i] < '0' || s[i] > '9')
- break;
- }
- }
- acount = 0;
-
- if (s[i] == '\0')
- {
- for (s = strtok(s,List_sep); s != NULL; s = strtok(NULL,List_sep))
- {
- anum[acount] = atoi(s);
- ++acount;
- }
- }
- else
- {
- /* we save old input only if NOT a list of article numbers */
- strcpy(Pattern,sbuf);
- if (s[0] == ART_MARK)
- {
- for (i=0; i < Page.h.artnum; ++i)
- {
- if (Page.b[i].art_mark == ART_MARK)
- {
- anum[acount] = Page.b[i].art_id;
- ++acount;
- }
- }
- }
- else
- {
- reg = regcmp(s,(char *) 0);
- if (reg != NULL)
- {
- for (i=0; i < Page.h.artnum; ++i)
- {
- if (regex(reg,Page.b[i].art_t) != NULL)
- {
- anum[acount] = Page.b[i].art_id;
- ++acount;
- }
- }
- regfree (reg);
- }
- else
- preinfo ("bad regular expression syntax");
- }
- }
-
- /* algorithm is inefficient, but we're only handling a few numbers */
- *list = '\0';
- for (i=0; i < Page.h.artnum; ++i)
- {
- for (j=0; j < acount && anum[j] != Page.b[i].art_id; ++j)
- ;
- if (neg == '!')
- {
- if (j < acount)
- continue;
- }
- else
- {
- if (j >= acount)
- continue;
- }
- sprintf (list,"%d ",Page.b[i].art_id);
- list += strlen(list);
- }
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'vnglob.c'" '(1473 characters)'
- if test -f 'vnglob.c'
- then
- echo shar: will not over-write existing file "'vnglob.c'"
- else
- cat << \SHAR_EOF > 'vnglob.c'
- /*
- ** vn news reader.
- **
- ** vnglob.c - global variables - see string.c also
- **
- ** see copyright disclaimer / history in vn.c source file
- */
-
- #include <stdio.h>
- #include "config.h"
- #include "head.h"
- #include "tune.h"
- #include "node.h"
- #include "page.h"
-
- /*
- global data structure
- */
- NODE **Newsorder = NULL; /* in order of fw_group calls */
-
- char *Editor, *Ps1, *Printer;
-
- int (*Massage)() = NULL;
- int (*Headedit)() = NULL;
- int (*Postfunc)() = NULL;
- int (*Mailfunc)() = NULL;
-
- char Erasekey, Killkey; /* user keys from stty */
- char *Orgdir; /* .newsrc file, and original pwd */
- char *Savefile = DEF_SAVE; /* file in which to save articles */
- char *Savedir; /* default directory for saved articles */
- char *Ccfile; /* author_copy file, stored /bin/mail fmt */
- char *Home; /* user's home */
-
- int Rot; /* rotation */
- int Headflag; /* header printing flag */
- int Digest; /* if non-zero, digest article */
- int More; /* if non-zero, clear screen between each page. Set by */
- /* user's MORE environment variable; if `-c', then set true */
-
- char *Ku, *Kd, *Kl, *Kr; /* Cursor movement capabilities */
-
- /* character translation arrays for commands */
- char Cxitop[128], Cxitor[128], Cxrtoi[128], Cxptoi[128];
-
- /*
- cur_page - current page displayed;
- lrec - last record
- l_allow - lines allowed for article display
- c_allow - columns allowed
- ncount = newsorder index
- */
- int Cur_page, Lrec, L_allow, C_allow, Ncount;
-
- int Nounsub, Listfirst;
- /*
- current page
- */
- PAGE Page;
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-